package cn.iocoder.an.module.business.service.equipmentkeepsetting;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.an.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.an.module.business.controller.admin.equipmentmanage.vo.EquipmentImportExcelVO;
import cn.iocoder.an.module.business.controller.admin.equipmentmanage.vo.ImportRespVO;
import cn.iocoder.an.module.business.dal.dataobject.equipmentkeepsettingtype.EquipmentKeepSettingTypeDO;
import cn.iocoder.an.module.business.dal.dataobject.equipmentkeeptype.EquipmentKeepTypeDO;
import cn.iocoder.an.module.business.dal.dataobject.equipmentmanage.EquipmentManageDO;
import cn.iocoder.an.module.business.dal.mysql.equipmentkeepsettingtype.EquipmentKeepSettingTypeMapper;
import cn.iocoder.an.module.business.dal.mysql.equipmentkeeptype.EquipmentKeepTypeMapper;
import cn.iocoder.an.module.business.service.equipmentkeepsettingtype.EquipmentKeepSettingTypeService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.micrometer.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

import cn.iocoder.an.module.business.controller.admin.equipmentkeepsetting.vo.*;
import cn.iocoder.an.module.business.dal.dataobject.equipmentkeepsetting.EquipmentKeepSettingDO;
import cn.iocoder.an.framework.common.pojo.PageResult;
import cn.iocoder.an.framework.common.pojo.PageParam;
import cn.iocoder.an.framework.common.util.object.BeanUtils;

import cn.iocoder.an.module.business.dal.mysql.equipmentkeepsetting.EquipmentKeepSettingMapper;

import static cn.iocoder.an.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.an.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.an.framework.common.util.collection.CollectionUtils.diffList;
import static cn.iocoder.an.module.business.enums.ErrorCodeConstants.*;

/**
 * 保养项设置 Service 实现类
 *
 * @author zzy
 */
@Service
@Validated
public class EquipmentKeepSettingServiceImpl implements EquipmentKeepSettingService {

    @Resource
    private EquipmentKeepSettingMapper equipmentKeepSettingMapper;

    @Resource
    private EquipmentKeepTypeMapper keepTypeMapper;

    @Resource
    private EquipmentKeepSettingTypeService settingTypeService;
    @Autowired
    private EquipmentKeepSettingTypeMapper equipmentKeepSettingTypeMapper;
    @Autowired
    private EquipmentKeepTypeMapper equipmentKeepTypeMapper;

    @Override
    public Long createEquipmentKeepSetting(EquipmentKeepSettingSaveReqVO createReqVO) {
        // 插入
        EquipmentKeepSettingDO equipmentKeepSetting = BeanUtils.toBean(createReqVO, EquipmentKeepSettingDO.class);
        equipmentKeepSettingMapper.insert(equipmentKeepSetting);

        // 返回
        return equipmentKeepSetting.getId();
    }

    @Override
    public void updateEquipmentKeepSetting(EquipmentKeepSettingSaveReqVO updateReqVO) {
        // 校验存在
        validateEquipmentKeepSettingExists(updateReqVO.getId());
        // 更新
        EquipmentKeepSettingDO updateObj = BeanUtils.toBean(updateReqVO, EquipmentKeepSettingDO.class);
        equipmentKeepSettingMapper.updateById(updateObj);
    }

    @Override
    public void deleteEquipmentKeepSetting(Long id) {
        // 校验存在
        validateEquipmentKeepSettingExists(id);

        //判断在保养项设置中有没有绑定

//        LambdaQueryWrapperX<EquipmentKeepSettingDO> queryWrapperX = new LambdaQueryWrapperX<>();
//        queryWrapperX.eq(EquipmentKeepSettingDO::getKeepType, id);
//        List<EquipmentKeepSettingDO> equipmentKeepSettingDOS = equipmentKeepSettingMapper.selectList(queryWrapperX);
//        if (equipmentKeepSettingDOS != null && !equipmentKeepSettingDOS.isEmpty()) {
//            throw exception(KEEP_DELETE_NOT);
//        }

        // 删除
        equipmentKeepSettingMapper.deleteById(id);
    }

    @Override
    public void deleteEquipmentKeepSettingListByIds(List<Long> ids) {
        // 删除
        equipmentKeepSettingMapper.deleteByIds(ids);
    }


    private void validateEquipmentKeepSettingExists(Long id) {
        if (equipmentKeepSettingMapper.selectById(id) == null) {
            throw exception(EQUIPMENT_KEEP_SETTING_NOT_EXISTS);
        }
    }

    @Override
    public EquipmentKeepSettingDO getEquipmentKeepSetting(Long id) {
        return equipmentKeepSettingMapper.selectById(id);
    }

    @Override
    public PageResult<EquipmentKeepSettingDO> getEquipmentKeepSettingPage(EquipmentKeepSettingPageReqVO pageReqVO) {

        if (pageReqVO.isShowCheckedOnly() && pageReqVO.getSettingId() != null) {
            EquipmentKeepSettingTypeDO equipmentKeepSettingType = settingTypeService.getEquipmentKeepSettingType(pageReqVO.getSettingId());
            List<Long> keepSetting = equipmentKeepSettingType.getKeepSetting();
            pageReqVO.setIds(keepSetting);
        }
        return equipmentKeepSettingMapper.selectPage(pageReqVO);
    }

    @Override
    public PageResult<EquipmentKeepSettingDO> getEquipmentKeepSettingPageNew(EquipmentKeepSettingPageReqVO pageReqVO) {
        Long keepType = pageReqVO.getKeepType();
        if (keepType != null) {
            EquipmentKeepSettingTypeDO equipmentKeepSettingTypeDO = equipmentKeepSettingTypeMapper.selectById(keepType);
            List<Long> keepSetting = equipmentKeepSettingTypeDO.getKeepSetting();
            pageReqVO.setIds(keepSetting);
            if (pageReqVO.getIds() == null || pageReqVO.getIds().isEmpty()) {
                return new PageResult<>();
            }
        }else{
            return new PageResult<>();
        }
        return equipmentKeepSettingMapper.selectPageNew(pageReqVO);
    }

    @Override
    public List<EquipmentKeepSettingDO> getEquipmentKeepSettingAllList(EquipmentKeepSettingPageReqVO pageReqVO) {

        if (pageReqVO.isShowCheckedOnly() && pageReqVO.getSettingId() != null) {
            EquipmentKeepSettingTypeDO equipmentKeepSettingType = settingTypeService.getEquipmentKeepSettingType(pageReqVO.getSettingId());
            List<Long> keepSetting = equipmentKeepSettingType.getKeepSetting();
            pageReqVO.setIds(keepSetting);
        }

        LambdaQueryWrapperX<EquipmentKeepSettingDO> queryWrapper = new LambdaQueryWrapperX<>();
        queryWrapper.eqIfPresent(EquipmentKeepSettingDO::getKeepType, pageReqVO.getKeepType())
                .likeIfPresent(EquipmentKeepSettingDO::getName, pageReqVO.getName())
                .eq(EquipmentKeepSettingDO::getStatus, pageReqVO.getStatus())
                .inIfPresent(EquipmentKeepSettingDO::getId, pageReqVO.getIds())
                .orderByDesc(EquipmentKeepSettingDO::getKeepType);
        return equipmentKeepSettingMapper.selectList(queryWrapper);
    }


    @Override
    public ImportRespVO importList(List<EquipmentSettingImportExcelVO> list, boolean isUpdateSupport) {
        // 1.1 参数校验
        if (CollUtil.isEmpty(list)) {
            throw exception(IMPORT_EQUIPMENT_MANAGE_NOT_EXISTS);
        }


        //2.记录成功或失败记录
        ImportRespVO respVO = ImportRespVO.builder().insertNameList(new ArrayList<>())
                .updateNameList(new ArrayList<>()).failureMap(new LinkedHashMap<>()).build();

        AtomicInteger count = new AtomicInteger(1);
        list.forEach(equipment -> {
            count.incrementAndGet();//记录行号

            // 2.1.1 校验保养项分类
            if (StringUtils.isEmpty(equipment.getKeepTypeName())) {
                respVO.getFailureMap().put("第" + count + "行数据", "保养项分类不能为空!");
                return;
            } else {
                //如果存在,使用名称查询ID
                try {
                    EquipmentKeepTypeDO equipmentKeepTypeDO = keepTypeMapper.selectFirstOne(EquipmentKeepTypeDO::getName, equipment.getKeepTypeName());
                    if (equipmentKeepTypeDO == null) {
                        respVO.getFailureMap().put("第" + count + "行数据", "该保养项分类不存在!");
                        return;
                    }
                    equipment.setKeepType(equipmentKeepTypeDO.getId());
                } catch (Exception e) {
                    respVO.getFailureMap().put("第" + count + "行数据", e.getMessage());
                    return;
                }
            }
            // 2.1.2 校验名称
            if (StringUtils.isEmpty(equipment.getName())) {
                respVO.getFailureMap().put("第" + count + "行数据", "保养项名称不能为空!");
                return;
            }

            // 2.1.3 校验保养方法
            if (StringUtils.isEmpty(equipment.getKeepMethod())) {
                respVO.getFailureMap().put("第" + count + "行数据", "保养方法不能为空!");
                return;
            }

            // 2.1.4 校验保养标准
            if (StringUtils.isEmpty(equipment.getKeepNorm())) {
                respVO.getFailureMap().put("第" + count + "行数据", "保养标准不能为空!");
                return;
            }
            equipmentKeepSettingMapper.insert(BeanUtils.toBean(equipment, EquipmentKeepSettingDO.class));
            respVO.getInsertNameList().add(equipment.getName());
        });
        return respVO;
    }

    @Override
    public ImportRespVO importListBind(List<EquipmentSettingBindImportExcelVO> list, boolean isUpdateSupport) {
        // 1.1 参数校验
        if (CollUtil.isEmpty(list)) {
            throw exception(IMPORT_EQUIPMENT_MANAGE_NOT_EXISTS);
        }


        //2.记录成功或失败记录
        ImportRespVO respVO = ImportRespVO.builder().insertNameList(new ArrayList<>())
                .updateNameList(new ArrayList<>()).failureMap(new LinkedHashMap<>()).build();

        AtomicInteger count = new AtomicInteger(1);
        list.forEach(equipment -> {
            count.incrementAndGet();//记录行号

            // 2.1.1 校验保养项分类
            if (StringUtils.isEmpty(equipment.getKeepTypeName())) {
                respVO.getFailureMap().put("第" + count + "行数据", "保养项分类不能为空!");
                return;
            }

            // 2.1.2 校验名称
            if (StringUtils.isEmpty(equipment.getName())) {
                respVO.getFailureMap().put("第" + count + "行数据", "保养项名称不能为空!");
                return;
            }

            EquipmentKeepSettingTypeDO equipmentKeepSettingTypeDO = equipmentKeepSettingTypeMapper.selectFirstOne(EquipmentKeepSettingTypeDO::getName, equipment.getKeepTypeName());
            if (equipmentKeepSettingTypeDO == null) {
                respVO.getFailureMap().put("第" + count + "行数据", "未查询到对应的保养分类!");
                return;
            }
            List<Long> keepSetting = equipmentKeepSettingTypeDO.getKeepSetting() != null ? equipmentKeepSettingTypeDO.getKeepSetting() : new ArrayList<>();

            LambdaQueryWrapperX<EquipmentKeepTypeDO> settingQueryWrapper = new LambdaQueryWrapperX<>();
            settingQueryWrapper.eq(EquipmentKeepTypeDO::getName, equipment.getName());
            List<EquipmentKeepTypeDO> typeList = equipmentKeepTypeMapper.selectList(settingQueryWrapper);
            if (typeList == null || typeList.isEmpty()) {
                respVO.getFailureMap().put("第" + count + "行数据", "未查询到对应的保养项目!");
                return;
            }


            for(EquipmentKeepTypeDO typeDO : typeList) {
                Long id = typeDO.getId();
                LambdaQueryWrapperX<EquipmentKeepSettingDO> settingQueryWrappers = new LambdaQueryWrapperX<>();
                settingQueryWrappers.eq(EquipmentKeepSettingDO::getKeepType, id);
                List<EquipmentKeepSettingDO> resultList = equipmentKeepSettingMapper.selectList(settingQueryWrappers);
                if (resultList == null || resultList.isEmpty()) {
                    continue;
                }else{
                    for(EquipmentKeepSettingDO settingDO : resultList) {
                        keepSetting.add(settingDO.getId());
                    }
                }
            }



            for(EquipmentKeepTypeDO typeDO : typeList) {
                keepSetting.add(typeDO.getId());
            }
            equipmentKeepSettingTypeDO.setKeepSetting(keepSetting);
            equipmentKeepSettingTypeMapper.updateById(equipmentKeepSettingTypeDO);
            respVO.getUpdateNameList().add(equipment.getName());
        });
        return respVO;
    }

    @Override
    public List<EquipmentKeepSettingRespVO> getEquipmentKeepSettingListByIds(List<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<EquipmentKeepSettingDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(EquipmentKeepSettingDO::getId, ids);
        List<EquipmentKeepSettingDO> equipmentKeepSettingDOS = equipmentKeepSettingMapper.selectList(queryWrapper);
        List<EquipmentKeepSettingRespVO> bean = BeanUtils.toBean(equipmentKeepSettingDOS, EquipmentKeepSettingRespVO.class);
        return bean;
    }


}